﻿/**
* 一个用户
* @typedef {Object} T_USER
* @property {String} Platform - 玩家进入的平台
* @property {Number} ID
* @property {String} RegisterTime
* @property {String} Token
* @property {String} Account
* @property {String} Password
* @property {Number} Phone
* @property {String} Name
* @property {String} LastLoginTime
* @property {String} LastRefreshLoginTime
*/
/** 需要登录针对某个用户的服务接口 */
const iu =
{
    install: (vue) => vue.config.globalProperties.iu = iu,
    /** 后端接口的URL */
    url:  '',
    /** 状态码对应错误信息，错误码和错误信息的对象会回调给event.onerror事件 */
    error: { 0: '请求已中止' },
    /**
    * @typedef RequestEvent
    * @type {Object}
    * @property {function(XMLHttpRequest)} onopen - 请求准备发送时的事件
    * @property {function(XMLHttpRequest)} onloading - 请求正在加载的事件(readyState = 3)
    * @property {function(XMLHttpRequest)} oncomplete - 请求完成时的事件(readyState = 4)
    * @property {function(XMLHttpRequest)} onsuccess - 请求成功的事件(readyState = 4 && status == 200 && !response.errCode)
    * @property {function({ errCode: number, errMsg: string })} onerror - 请求发生错误时的事件(readyState = 4 && (status != 200 || response.errCode))
    * @property {function(ProgressEvent)} onprogress - 上传文件请求的进度事件
    */
    /** 接口请求的全局事件
    * @type {RequestEvent} */
    __event: undefined,
    /** 接口请求的全局事件
    * @type {RequestEvent} */
    event: undefined,
    /** 本次接口请求的临时事件，onprogress以外的全局事件任然会触发，临时事件优先于全局事件触发
    * @param {RequestEvent} event */
    eventonce(event)
    {
        this.__event = Object.assign({}, this.__event, event);
        return this;
    },
    /** 发送接口
    * @param {String} url - 接口url
    * @param {XMLHttpRequestBodyInit} [data] - 数据，可以是FormData或a=1&b=2格式的字符串
    * @param {('POST' | 'GET')} method - 默认POST
    */
    send(url, data, method = 'POST')
    {
        return new Promise((resolve, reject) =>
        {
            const req = new XMLHttpRequest();
            const event = this.__event;
            this.__event = undefined;
            req.onreadystatechange = async () =>
            {
                if (req.readyState == 4)
                {
                    event?.oncomplete?.(req) | this.event?.oncomplete?.(req);
                    if (req.status == 200)
                    {
                        let obj = null;
                        switch (req.responseType)
                        {
                            case 'text': if (req.response) obj = JSON.parse(req.responseText); break;
                            case 'blob':
                            if (req.response.type == 'text/plain') await req.response.text().then((value) => obj = JSON.parse(value));
                            else obj = req.response;
                            break;
                        }
                        if (obj && obj.errCode)
                        event?.onerror?.(obj) | this.event?.onerror?.(obj) | reject(obj);
                        else
                        event?.onsuccess?.(obj) | this.event?.onsuccess?.(obj) | resolve(obj);
                    }
                    else
                    {
                        let error = { errCode: req.status, errMsg: '' };
                        error.errMsg = this.error[req.status] || req.statusText;
                        event?.onerror?.(error) | this.event?.onerror?.(error) | reject(error);
                    }
                }
                else if (req.readyState == 3) event?.onloading?.(req) | this.event?.onloading?.(req);
            }
            req.open(method, this.url + url, true);
            req.upload.onprogress = event?.onprogress || this.event?.onprogress;
            req.responseType = 'text';
            if (event?.onopen) event.onopen(req);
            else req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded;charset=utf-8');
            this.event?.onopen?.(req);
            req.send(data);
        });
    },
    /** 调用下载文件的接口前调用
    * @param {string} filename - 下载文件的名字，例如download.csv
    * @example
    * api.download('download.csv').downloadCSV()
    */
    download(filename)
    {
        return this.eventonce(
        {
            oncomplete(req)
            {
                const a = window.document.createElement('a');
                a.href = URL.createObjectURL(req.response);
                a.download = filename;
                a.click();
            }
        })
    },
    /**
    * 用户信息
    * @returns {Promise<any>}
    */
    UserInfo()
    {
        return this.send("3/UserInfo");
    },
    /**
    * @typedef UserModifyPassword
    * @property {String} opass - 原密码
    * @property {String} npass - 新密码
    */
    /**
    * 用户修改密码
    * @param {String | UserModifyPassword} opass - 原密码
    * @example
    * {
    *   opass: undefined,
    *   npass: undefined,
    * }
    * @param {String} npass - 新密码
    * @returns {Promise<Boolean>}
    */
    UserModifyPassword(opass, npass)
    {
        arguments.length == 1 && ({ opass, npass } = arguments[0])
        const data = [];
        if (opass) data.push("opass=" + encodeURIComponent(opass));
        if (npass) data.push("npass=" + encodeURIComponent(npass));
        return this.send("3/UserModifyPassword", data.join('&'));
    },
    /**
    * @typedef UserModifyPhone
    * @property {String} phone - 新手机号
    * @property {String} code - 验证码
    */
    /**
    * 用户修改手机号
    * @param {String | UserModifyPhone} phone - 新手机号
    * @example
    * {
    *   phone: undefined,
    *   code: undefined,
    * }
    * @param {String} code - 验证码
    * @returns {Promise<Boolean>}
    */
    UserModifyPhone(phone, code)
    {
        arguments.length == 1 && ({ phone, code } = arguments[0])
        const data = [];
        if (phone) data.push("phone=" + encodeURIComponent(phone));
        if (code) data.push("code=" + encodeURIComponent(code));
        return this.send("3/UserModifyPhone", data.join('&'));
    },
    /**
    * 用户退出登录
    * @returns {Promise<any>}
    */
    UserExitLogin()
    {
        return this.send("3/UserExitLogin");
    },
};
export default iu
